﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Xml.Serialization;
using DataSimDLL;
using System.Runtime.InteropServices;

namespace BDSim
{
    /// <summary>
    /// 卫星模型
    /// </summary>
    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class Satellite : SpaceBase
    {
        #region 字段

        private Constellation _Parent;
        private SatOrbit _Orbit=new SatOrbit();
        private SatClock _Clock=new SatClock();
        private SatelliteDataProvider _DataProvider = new SatelliteDataProvider();
        private bool _IsShowSatTrack = true;
        private NavMessage _NavMessage = new NavMessage();
   
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
        private double[] _PhaseOff = { 0.3940, 0, 1.5613 };


        /// <summary>
        /// 按照轨道积分步长存储的卫星ECI、ECF位置速度
        /// </summary>
        [XmlIgnore]
        public List<OrbitSimData> OrbitPVList=new List<OrbitSimData>();


        /// <summary>
         /// 存储仿真钟差五步点数据数据
        /// </summary>
        [XmlIgnore]
         public List<AtomicClockErr> SatAtomicClkList = new List<AtomicClockErr>();
        /// <summary>
        /// 卫星实体的时间控制
        /// </summary>
        [XmlIgnore]
        public SimParam simParam;

        /// <summary>
        /// 卫星3D模型
        /// </summary>
        [XmlIgnore]
        public Satellite3DModel _3DModel = new Satellite3DModel();
        #endregion

        #region 属性

        /// <summary>
        /// 该卫星所属星座
        /// </summary>
        [XmlIgnore,Browsable(false)]
        public Constellation Parent
        {
            get { return _Parent; }
            set { _Parent = value; }
        }

        [Category("基本信息"), PropertyOrder(1)]
        public string Name
        {
            get { return _Name; }
            set
            {
                if (Parent!= null && Parent.Parent != null)
                {
                    foreach (var constellation in Parent.Parent.ConstellationList)
                    {
                        foreach (var sat in constellation.SatelliteCollection)
                        {
                            if (sat.Name == value)
                            {
                                DlgReportPropertyInfo("名字无效，已存在名为“" + value + "”的卫星!");
                                return;
                            }
                        }
                    }
                }
                _Name = value;
                NotifyPropertyChanged("Name");
            }
        }
 
        /// <summary>
        /// 卫星轨道
        /// </summary>
        [CategoryAttribute("卫星轨道"), DescriptionAttribute("卫星轨道参数"), DisplayName("轨道参数"),TypeConverter(typeof(PropertySorter))]
        public SatOrbit Orbit
        {
            get { return _Orbit; }
            set { _Orbit = value; }
        }

        /// <summary>
        /// 卫星钟差
        /// </summary>
        [CategoryAttribute("卫星钟差"), DescriptionAttribute("卫星钟差参数"), DisplayName("钟差参数"), TypeConverter(typeof(PropertySorter))]
        public SatClock Clock
        {
            get { return _Clock; }
            set { _Clock = value; }
        }

        /// <summary>
        /// 数据提供
        /// </summary>
        [XmlIgnore,Browsable(false)]
        public SatelliteDataProvider DataProvider
        {
            get { return _DataProvider; }
            set { _DataProvider = value; }
        }

        /// <summary>
        /// 星下点轨迹是否显示
        /// </summary>
        [CategoryAttribute("星下点轨迹"), DescriptionAttribute("星下点轨迹显示控制开关")]
        public bool IsShowSatTrack
        {
            get { return _IsShowSatTrack; }
            set { _IsShowSatTrack = value; }
        }

        /// <summary>
        /// 导航电文
        /// </summary>
        [XmlIgnore,Browsable(false)]
        public NavMessage NavMessage
        {
            get { return _NavMessage; }
            set { _NavMessage = value; }
        }
        
        /// <summary>
        /// 卫星的相位中心偏移
        /// </summary>
        [CategoryAttribute("相位中心偏移量"), DescriptionAttribute("卫星在本体坐标系（X、Y、Z方向）的相位中心偏移，本体坐标系：原点为卫星质心，Z轴指向地心，Y轴指向卫星太阳帆板方向，与卫星—太阳连线和星—地连线的矢量积方向一致，X轴方向与Y和Z正交"), ReadOnly(true)]
        public double[] PhaseOff
        {
            get { return _PhaseOff; }
            set { _PhaseOff = value; }
        }

        #endregion


        #region 方法

        /// <summary>
        /// 构造函数
        /// </summary>
        public Satellite()
        {
            _Orbit.Parent = this;
            _Clock.Parent = this;
            _DataProvider.Parent = this;
            _DataProvider.DefineCommand();
            Menu.ItemsSource = _DataProvider.MenuCommandList;
        }


        /// <summary>
        /// 单步实时运行
        /// </summary>
        public void SatStepSim()
        {
            ///实时计算轨道
            _Orbit.RealECIPV = RealTimePV(GlobalCurrentTime);
            TimeSpaceDll.ECI2ECF(_Orbit.RealECIPV, 0, 0, out _Orbit.RealECFPV);

            ///实时更新3D可视化的轨道
            _3DModel.UpDate3DModelPos(_Orbit.RealECIPV);

            ///实时更新钟差
            _Clock.Clk_Err = RealTimeClkErr(GlobalCurrentTime);
        }

        #region 初始化
        public override void Init()
        {
            OrbitPVList.Clear();
            //OrbitBackDiffList.Clear();

            SatAtomicClkList.Clear();
            //时间初始化
            simParam.pStartTime = BDSimObject.GlobalStartTime;
            simParam.simClks = 0;
            simParam.simStepInt = (int)(BDSimObject.GlobalStepSize * 1e6);

            ///计算初始时刻的位置速度
            _Orbit.Init();

            //3D模型初始化
            _3DModel.SetInitPos(_Orbit.RealECIPV);

            ///存储第一步的位置速度
           // OrbitBackDiffList.Add(_Orbit.OrbBackDif);
            OrbitSimData temppv = new OrbitSimData();
            temppv.ID = this.Id;
            temppv.Name = this.Name;
            temppv.SatPV_ECI = _Orbit.RealECIPV;         

            OrbitPVList.Add(temppv);

            //轨道数据仿真，间隔为积分步长
            PreviousOrbitSim();

            //赋值初始轨道
            _Orbit.RealECIPV = OrbitPVList[0].SatPV_ECI;
            TimeSpaceDll.ECI2ECF(_Orbit.RealECIPV, 0, 0, out _Orbit.RealECFPV);
       
            //钟差初始化
            _Clock.Init();

            ///存储第一步的钟差五步点
            SatAtomicClkList.Add(_Clock.StepClkErr);
            PreviousClkSim();
           
            //赋值初始钟差
            _Clock.RealOut(SatAtomicClkList[0]);

            simParam.simClks = 0;
            //初始化完成反馈任务执行量
            DlgAddCompleteMission();
        }
        #endregion

        #region 单步运行
        public override void StepRun()
        {
            SatStepSim();
        }
        #endregion


        /// <summary>
        /// 提前仿真轨道数据
        /// </summary>
        public void PreviousOrbitSim()
        {
            double EndJD = BDSimObject.GlobalEndTime.JD;

            ///若存在对应的主控站
            GroundSegment temp = (Parent.Parent.Parent as Scenario).SegmentColletion[2] as GroundSegment;
            foreach (var item in temp.SubGroundSegmentList)
            {
                if (item.Type == Parent.ConstellationFeature.ConstellationType)
                {
                    foreach (var staitem in item.GroundList)
                    {
                        if (staitem.Type == EStationType.MasterStation & staitem.StationList.Count > 0 )
                        {

                            //获取仿真时所跨越长的“整小时”数，就是有几个小时
                            double tempDouble = (BDSimObject.GlobalEndTime.JD - BDSimObject.GlobalStartTime.JD) / ((double)3600 / 86400);
                            int hourNum = (int)Math.Ceiling((Convert.ToDouble(tempDouble.ToString("0.00000"))));

                            //拟合一组钟差需要2个小时，不足补齐的方式得到计算结束时刻JD
                            EndJD = BDSimObject.GlobalStartTime.JD + (hourNum + 1) * ((double)3600 / 86400);
                        }
                    }
                }
            }

            UTCTime tempTime = BDSimObject.GlobalStartTime;// 把开始时间赋值给临时时间          
            int predctStep =_Orbit.IntegrationParam.StepSize;
            SimParam tempSimparam = simParam; //把仿真步长、节拍数、开始时间等赋值给临时仿真参数
            tempSimparam.simStepInt = (int)(predctStep * 1e6);
            tempSimparam.simClks = 1;
            for (; tempTime.JD < EndJD; tempSimparam.simClks++)
            {
                ///时间仿真
                double nowTime = tempSimparam.simClks * predctStep;
                tempTime.IntJD = BDSimObject.GlobalStartTime.IntJD + Math.Floor(nowTime / 86400.0);
                tempTime.DouJD = BDSimObject.GlobalStartTime.DouJD + nowTime / 86400.0 - Math.Floor(nowTime / 86400.0);
                tempTime.JD = tempTime.IntJD + tempTime.DouJD;

                ///轨道计算
                _Orbit.SimParam = tempSimparam;
                _Orbit.FixedStepOut();
                _Orbit.RealOut(_Orbit.OrbBackDif);

                
                OrbitSimData temppv = new OrbitSimData();
                temppv.ID = this.Id;
                temppv.Name = this.Name;
                temppv.SatPV_ECI = _Orbit.RealECIPV;
              //  temppv.SatPV_ECF = _Orbit.RealECFPV;
                OrbitPVList.Add(temppv);
            }
        }

        /// <summary>
        /// 提前仿真钟差整步点数据
        /// </summary>
        private void PreviousClkSim()
        {
            double EndJD = BDSimObject.GlobalEndTime.JD;

            ///若存在对应的主控站
            GroundSegment temp = (Parent.Parent.Parent as Scenario).SegmentColletion[2] as GroundSegment;
            foreach (var item in temp.SubGroundSegmentList)
            {
                if (item.Type == Parent.ConstellationFeature.ConstellationType)
                {
                    foreach (var staitem in item.GroundList)
                    {
                        if (staitem.Type == EStationType.MasterStation & staitem.StationList.Count > 0)
                        {

                            //获取仿真时所跨越长的“整小时”数，就是有几个小时
                            double tempDouble = (BDSimObject.GlobalEndTime.JD - BDSimObject.GlobalStartTime.JD) / ((double)3600 / 86400);
                            int hourNum = (int)Math.Ceiling((Convert.ToDouble(tempDouble.ToString("0.00000"))));

                            //拟合一组钟差需要2个小时，不足补齐的方式得到计算结束时刻JD
                            EndJD = BDSimObject.GlobalStartTime.JD + (hourNum + 1) * ((double)3600 / 86400);
                        }
                    }
                }
            }

            UTCTime tempTime = BDSimObject.GlobalStartTime; ;            // 把开始时间赋值给临时时间
            SimParam SimParamTemp = simParam;          //把仿真步长、节拍数、开始时间等赋值给临时仿真参数
            SimParamTemp.simStepInt = (int)(_Clock.Clk_tao * 1e6);

            SimParamTemp.simClks = 1;
            for (;  tempTime.JD<EndJD; SimParamTemp.simClks++)
            {
                //时间仿真
                double nowTime = SimParamTemp.simClks * _Clock.Clk_tao;
                tempTime.IntJD = BDSimObject.GlobalStartTime.IntJD + Math.Floor(nowTime / 86400.0);
                tempTime.DouJD = BDSimObject.GlobalStartTime.DouJD + nowTime / 86400.0 - Math.Floor(nowTime / 86400.0);
                tempTime.JD = tempTime.IntJD + tempTime.DouJD;
                //钟差计算
                _Clock.simParam = SimParamTemp;
                _Clock.FixedStepOut();

                SatAtomicClkList.Add(_Clock.StepClkErr);
            }
            //钟差数据插值（间隔为仿真步长）
          //  InterSatClkErrList = GenerateStepCLKErr();
        }
        

        #endregion

        #region 按照仿真步长插值轨道和钟差数据               

        public List<OrbitSimData> GenerateStepOrbit(int simStep = 0)
        {
            List<OrbitSimData> orbitSimDataList = new List<OrbitSimData>();

            #region 根据后插表计算          
           
            //try
            //{
            //    if (BDSimObject.GlobalStatus != ESimStatus.UnInited && BDSimObject.GlobalStatus != ESimStatus.Run && OrbitBackDiffList != null && OrbitBackDiffList.Count != 0)
            //    {
            //        //仿真步长默认为场景给卫星设定的步长
            //        SimParam tempSimParam = simParam;

            //        //当用户设定了大于0的自定义步长时，即使用
            //        if (simStep > 0)
            //        {
            //            tempSimParam.simStepInt = (int)(simStep * 1e6);
            //        }
            //        tempSimParam.simClks = 0;
            //        while (true)
            //        {
            //            int listID = (int)Math.Floor((tempSimParam.simClks * (tempSimParam.simStepInt * 1e-6)) / _Orbit.IntegrationParam.StepSize);
            //            Orbit.SimParam = tempSimParam;//更新轨道模块实时时间 
            //            Orbit.RealOut(OrbitBackDiffList[listID]);///轨道仿真输出
            //            NodePosVel tempSatECIPV = Orbit.RealECIPV;//获取输出的ECI位置   
            //            NodePosVel tempSatECFPV = Orbit.RealECFPV;

            //            OrbitSimData temp = new OrbitSimData() { ID = this.Id, Name = this.Name, SatPV_ECI = tempSatECIPV };
            //            orbitSimDataList.Add(temp);
            //            if (listID >= OrbitBackDiffList.Count() - 1)//如果超出了存储的后查表的时间范围，则返回
            //            {
            //                break;
            //            }
            //            tempSimParam.simClks++;
            //        }
            //    }
            //}
            //catch
            //{ }
            #endregion

            Queue<NodePosVel> satPVQueue = new Queue<NodePosVel>();

            try
            {
                if (BDSimObject.GlobalStatus != ESimStatus.UnInited && BDSimObject.GlobalStatus != ESimStatus.Run && OrbitPVList != null && OrbitPVList.Count != 0)
                {
                    //仿真步长默认为场景给卫星设定的步长
                    SimParam tempSimParam = simParam;

                    //当用户设定了大于0的自定义步长时，即使用
                    if (simStep > 0)
                    {
                        tempSimParam.simStepInt = (int)(simStep * 1e6);
                    }
                    tempSimParam.simClks = 0;
                    int num = 10;//拉格朗日插值
                    double[] satT = new double[num];
                    double[] satX = new double[num];
                    double[] satY = new double[num];
                    double[] satZ = new double[num];
                    double[] satVX = new double[num];
                    double[] satVY = new double[num];
                    double[] satVZ = new double[num];
                   // int satIndex = 0;
                    //int prelistID = 0;
                    while (true)
                    {
                        double nowTime = tempSimParam.simClks * (((double)tempSimParam.simStepInt) * 1e-6);
                        int listID = (int)Math.Floor(nowTime / _Orbit.IntegrationParam.StepSize);
                        if (listID >= OrbitPVList.Count() - 1)//如果超出了存储的轨道的时间范围，则返回
                        {
                            break;
                        }
                        //if (tempSimParam.simClks == 0)
                        //{
                        //    for (int i = 0; i < num; i++)
                        //    {
                        //        satPVQueue.Enqueue(OrbitPVList[i].SatPV_ECI);
                        //        satIndex++;
                        //    }
                        //}
                        //else
                        //{
                        //    if (listID > num / 2 - 1 & (OrbitPVList.Count - listID) > num / 2 & (listID != prelistID))
                        //    {
                        //        satPVQueue.Dequeue();
                        //        satPVQueue.Enqueue(OrbitPVList[satIndex].SatPV_ECI);
                        //        satIndex++;
                        //        prelistID = listID;
                        //    }
                        //}

                        //List<NodePosVel> temp = satPVQueue.ToList();
                        //for (int i = 0; i < num; i++)
                        //{
                        //    satT[i] = temp[i].Epoch.JD;
                        //    satX[i] = temp[i].X;
                        //    satY[i] = temp[i].Y;
                        //    satZ[i] = temp[i].Z;
                        //    satVX[i] = temp[i].VX;
                        //    satVY[i] = temp[i].VY;
                        //    satVZ[i] = temp[i].VZ;
                        //}

                        if (OrbitPVList.Count >= 10)
                        {
                            if (listID > num / 2 - 1 & (OrbitPVList.Count - listID) > num / 2)
                            {
                                for (int i = 0; i < 10; i++)
                                {
                                    satT[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.Epoch.JD;
                                    satX[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.X;
                                    satY[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.Y;
                                    satZ[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.Z;
                                    satVX[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.VX;
                                    satVY[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.VY;
                                    satVZ[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.VZ;
                                }
                            }
                            else if (listID <= num / 2 - 1)
                            {
                                for (int i = 0; i < num; i++)
                                {
                                    satT[i] = OrbitPVList[i].SatPV_ECI.Epoch.JD;
                                    satX[i] = OrbitPVList[i].SatPV_ECI.X;
                                    satY[i] = OrbitPVList[i].SatPV_ECI.Y;
                                    satZ[i] = OrbitPVList[i].SatPV_ECI.Z;
                                    satVX[i] = OrbitPVList[i].SatPV_ECI.VX;
                                    satVY[i] = OrbitPVList[i].SatPV_ECI.VY;
                                    satVZ[i] = OrbitPVList[i].SatPV_ECI.VZ;
                                }
                            }
                            else
                            {
                                for (int i = 0; i < num; i++)
                                {
                                    satT[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.Epoch.JD;
                                    satX[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.X;
                                    satY[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.Y;
                                    satZ[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.Z;
                                    satVX[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.VX;
                                    satVY[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.VY;
                                    satVZ[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.VZ;
                                }
                            }
                        }                        

                        UTCTime curTime = new UTCTime();
                        curTime.IntJD = BDSimObject.GlobalStartTime.IntJD + Math.Floor(nowTime / 86400.0);
                        curTime.DouJD = BDSimObject.GlobalStartTime.DouJD + nowTime / 86400.0 - Math.Floor(nowTime / 86400.0);
                        curTime.JD = curTime.IntJD + curTime.DouJD;
                        TimeSpaceDll.CAL2UTC(out curTime, 2);
                        if (Math.Round(curTime.sec, 1) == 60)
                        {
                            curTime.sec = 0;
                            curTime.min++;
                        }

                        NodePosVel temppv = new NodePosVel();
                        temppv.Epoch = curTime;
                        CInterpolateDLL.Lagrange(curTime.JD, num, satT, satX, ref temppv.x);
                        CInterpolateDLL.Lagrange(curTime.JD, num, satT, satY, ref temppv.y);
                        CInterpolateDLL.Lagrange(curTime.JD, num, satT, satZ, ref temppv.z);
                        CInterpolateDLL.Lagrange(curTime.JD, num, satT, satVX, ref temppv.vx);
                        CInterpolateDLL.Lagrange(curTime.JD, num, satT, satVY, ref temppv.vy);
                        CInterpolateDLL.Lagrange(curTime.JD, num, satT, satVZ, ref temppv.vz);

                        OrbitSimData tempdata = new OrbitSimData() { ID = this.Id, Name = this.Name, SatPV_ECI = temppv };
                        orbitSimDataList.Add(tempdata);
 
                        tempSimParam.simClks++;
                    }
                }
            }
            catch
            { }

            return orbitSimDataList;
        }

        /// <summary>
        /// 产生指定步长的钟差数据，默认步长为系统仿真步长
        /// </summary>
        /// <param name="simStep">仿真步长，单位s</param>
        /// <returns></returns>
        public List<ClkSimData> GenerateStepCLKErr(double simStep = 0)
        {
            List<ClkSimData> clkErrList = new List<ClkSimData>();
            try
            {
                if (BDSimObject.GlobalStatus != ESimStatus.UnInited && BDSimObject.GlobalStatus != ESimStatus.Run && SatAtomicClkList != null && SatAtomicClkList.Count != 0)
                {
                    SimParam tempSimParam = simParam;
                    //当用户设定了大于0的自定义步长时，即使用
                    if (simStep > 0)
                    {
                        tempSimParam.simStepInt = (int)(simStep * 1000000);
                    }
                    tempSimParam.simClks = 0;
                    DateTime simTime = BDSimObject.GlobalStartTime.ToDateTime();
                    while (true)
                    {
                        int clkListID = (int)Math.Floor((tempSimParam.simClks * (tempSimParam.simStepInt * 1e-6)) / _Clock.Clk_tao);
                        if (clkListID >= SatAtomicClkList.Count() - 1)//如果超出了LIST存储的时间范围，则返回
                        {
                            break;
                        }
                        _Clock.simParam = tempSimParam;//更新轨道模块实时时间 
                        _Clock.RealOut(SatAtomicClkList[clkListID]);
                        ClkSimData tempData = new ClkSimData() { ID = this.Id, Name = this.Name, ClkError = _Clock.Clk_Err, SimTime = new UTCTime(simTime.Year, simTime.Month, simTime.Day, simTime.Hour, simTime.Minute, simTime.Second, 0) };
                        TimeSpaceDll.CAL2UTC(out tempData.SimTime, 1);
                        clkErrList.Add(tempData);

                        simTime = simTime.AddSeconds(tempSimParam.simStepInt * 1e-6);
                        tempSimParam.simClks++;
                    }
                }

                //if (BDSimObject.GlobalStatus != ESimStatus.UnInited && BDSimObject.GlobalStatus != ESimStatus.Run && SatClkErrList != null && SatClkErrList.Count != 0)
                //{
                //    SimParam tempSimParam = simParam;
                //    //当用户设定了大于0的自定义步长时，即使用
                //    if (simStep > 0)
                //    {
                //        tempSimParam.simStepInt = (int)(simStep * 1000000);
                //    }
                //    DateTime simTime = BDSimObject.GlobalStartTime.ToDateTime();

                //    tempSimParam.simClks = 0;
                //    int num = 6;//拉格朗日插值
                //    double[] clkT = new double[num];
                //    double[] clkErr = new double[num];
                //    Queue<ClkSimData> clkQueue = new Queue<ClkSimData>();
                //    int prelistID = 0;
                //    int clkIndex = 0;
                //    while (true)
                //    {
                //        int clkListID = (int)Math.Floor((tempSimParam.simClks * (tempSimParam.simStepInt * 1e-6)) / _Clock.Clk_tao);

                //        if (tempSimParam.simClks == 0)
                //        {
                //            for (int i = 0; i < num; i++)
                //            {
                //                clkQueue.Enqueue(SatClkErrList[i]);
                //                clkIndex++;
                //            }                           
                //        }
                //        else
                //        {
                //            if (clkListID > num / 2 - 1 & (SatClkErrList.Count - clkListID) > num / 2 & (clkListID != prelistID))
                //            {
                //                clkQueue.Dequeue();
                //                clkQueue.Enqueue(SatClkErrList[clkIndex]);
                //                clkIndex++;
                //                prelistID = clkListID;
                //            }
                //        }
                //        List<ClkSimData> temp = clkQueue.ToList();
                //        for (int i = 0; i < num; i++)
                //        {
                //            clkT[i] = temp[i].SimTime.JD;
                //            clkErr[i] = temp[i].ClkError;
                //        }
                //        ClkSimData tempData = new ClkSimData() { ClkError = _Clock.Clk_Err, SimTime = new UTCTime(simTime.Year, simTime.Month, simTime.Day, simTime.Hour, simTime.Minute, simTime.Second, 0) };
                //        TimeSpaceDll.CAL2UTC(out tempData.SimTime, 1);
                //        CInterpolateDLL.Lagrange(tempData.SimTime.JD, num, clkT, clkErr, ref tempData.ClkError);
                //        clkErrList.Add(tempData);

                //        if (clkListID >= SatClkErrList.Count() - 1)//如果超出了LIST存储的时间范围，则返回
                //        {
                //            break;
                //        }
                //        simTime = simTime.AddSeconds(tempSimParam.simStepInt * 1e-6);
                //        tempSimParam.simClks++;
                //    }
                //}
            }
            catch (Exception)
            {
               
            }
            return clkErrList;
        }


        /// <summary>
        /// 插值得到卫星实时的ECI位置
        /// </summary>
        /// <param name="CurTime">当前计算时间</param>
        /// <returns>计算时间对应的轨道</returns>
        public NodePosVel RealTimePV(UTCTime CurTime)
        {
            NodePosVel CurPV = new NodePosVel();
            TimeSpaceDll.CAL2UTC(out CurTime, 1);
            double nowTime = (CurTime.JD - GlobalStartTime.JD) * 86400 + 0.0001;
            int listID = (int)Math.Floor(nowTime / Orbit.IntegrationParam.StepSize);
            int num = 10;
            double[] satT = new double[num];
            double[] satX = new double[num];
            double[] satY = new double[num];
            double[] satZ = new double[num];
            double[] satVX = new double[num];
            double[] satVY = new double[num];
            double[] satVZ = new double[num];
            if (OrbitPVList.Count >= 10)
            {
                if (listID > num / 2 - 1 & (OrbitPVList.Count - listID) > num / 2)
                {
                    for (int i = 0; i < 10; i++)
                    {
                        satT[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.Epoch.JD;
                        satX[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.X;
                        satY[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.Y;
                        satZ[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.Z;
                        satVX[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.VX;
                        satVY[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.VY;
                        satVZ[i] = OrbitPVList[listID - num / 2 + 1 + i].SatPV_ECI.VZ;
                    }
                }
                else if (listID <= num / 2 - 1)
                {
                    for (int i = 0; i < num; i++)
                    {
                        satT[i] = OrbitPVList[i].SatPV_ECI.Epoch.JD;
                        satX[i] = OrbitPVList[i].SatPV_ECI.X;
                        satY[i] = OrbitPVList[i].SatPV_ECI.Y;
                        satZ[i] = OrbitPVList[i].SatPV_ECI.Z;
                        satVX[i] = OrbitPVList[i].SatPV_ECI.VX;
                        satVY[i] = OrbitPVList[i].SatPV_ECI.VY;
                        satVZ[i] = OrbitPVList[i].SatPV_ECI.VZ;
                    }
                }
                else
                {
                    for (int i = 0; i < num; i++)
                    {
                        satT[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.Epoch.JD;
                        satX[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.X;
                        satY[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.Y;
                        satZ[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.Z;
                        satVX[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.VX;
                        satVY[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.VY;
                        satVZ[i] = OrbitPVList[OrbitPVList.Count - num + i].SatPV_ECI.VZ;
                    }
                }
            }

            CurPV.Epoch = CurTime;
            CInterpolateDLL.Lagrange(CurTime.JD, num, satT, satX, ref CurPV.x);
            CInterpolateDLL.Lagrange(CurTime.JD, num, satT, satY, ref CurPV.y);
            CInterpolateDLL.Lagrange(CurTime.JD, num, satT, satZ, ref CurPV.z);
            CInterpolateDLL.Lagrange(CurTime.JD, num, satT, satVX, ref CurPV.vx);
            CInterpolateDLL.Lagrange(CurTime.JD, num, satT, satVY, ref CurPV.vy);
            CInterpolateDLL.Lagrange(CurTime.JD, num, satT, satVZ, ref CurPV.vz);

            return CurPV;
        }

        /// <summary>
        /// 实时计算卫星钟差
        /// </summary>
        /// <param name="CurTime"></param>
        /// <returns></returns>
        public double RealTimeClkErr(UTCTime CurTime)
        {
            double ClkErr = 0;
            TimeSpaceDll.CAL2UTC(out CurTime, 1);
            double nowTime = (CurTime.JD - GlobalStartTime.JD) * 86400 + 0.0001;
            int TimeId = 0;
            TimeId = (int)Math.Floor(nowTime / _Clock.Clk_tao);
            AtomicClockErr AtoClk = SatAtomicClkList[TimeId];
            //实时计算钟差
            ClkTrp_Input clkTrp_Input;
            ClkTrp_Param clkTrp_Param;
            ClkTrp_Output clkTrp_Output;
            clkTrp_Input.tobs = nowTime;
            clkTrp_Input.a = new double[7];
            clkTrp_Input.a[0] = TimeId;
            clkTrp_Input.a[1] = _Clock.Clk_tao;
            clkTrp_Input.a[2] = AtoClk.m_sb2;
            clkTrp_Input.a[3] = AtoClk.m_sb1;
            clkTrp_Input.a[4] = AtoClk.m_s0;
            clkTrp_Input.a[5] = AtoClk.m_sa1;
            clkTrp_Input.a[6] = AtoClk.m_sa2;
            clkTrp_Param.Iclo = 1;
            CClkSimDLL.ClockErr_Trp(clkTrp_Input, clkTrp_Param, out clkTrp_Output);
            ClkErr = clkTrp_Output.DeltClock;//实时计算钟差

            return ClkErr;
        }

        #endregion


    }
}   
